package com.songlanyun.modules.account.controller.api;

import cn.hutool.core.map.MapUtil;
import com.songlanyun.common.enums.GoodsConstant;
import com.songlanyun.common.enums.MemberConstant;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.utils.R;
import com.songlanyun.common.utils.RedisKeys;
import com.songlanyun.common.utils.RedisUtils;
import com.songlanyun.common.utils.aes.AESUtil;
import com.songlanyun.common.validator.ValidatorUtils;
import com.songlanyun.modules.account.controller.common.AbstractApiController;
import com.songlanyun.modules.account.dao.UserInfoDao;
import com.songlanyun.modules.account.entity.AccountEntity;
import com.songlanyun.modules.account.entity.UserInfoEntity;
import com.songlanyun.modules.account.model.vo.*;
import com.songlanyun.modules.account.service.AccountService;
import com.songlanyun.modules.account.service.CommonService;
import com.songlanyun.modules.account.service.UserActivationService;
import com.songlanyun.modules.account.service.UserInfoService;
import com.songlanyun.modules.config.model.PointGradeConfigDTO;
import com.songlanyun.modules.config.service.PointGradeConfigService;
import com.songlanyun.modules.exception.MemberException;
import com.songlanyun.modules.rabbitmq.MqConstant;
import com.songlanyun.modules.rabbitmq.service.SendMsgService;
import com.songlanyun.modules.user.form.MobileForm;
import com.songlanyun.modules.user.form.PasswordForm;
import com.songlanyun.pay.configure.AliPayConfig;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 会员帐号表（会员的基本信息与关系）
 *
 * @author Mark
 * @email sunlightcs@gmail.com
 * @date 2020-11-02 15:51:10
 */
@RestController
@RequestMapping("api/account")
public class AccountApiController extends AbstractApiController {

    @Resource
    private AccountService accountService;

    @Resource
    private CommonService commonService;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private PointGradeConfigService pointGradeConfigService;

    @Resource
    private UserInfoDao userInfoDao;

    @Autowired
    private UserActivationService userActivationService;

    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private SendMsgService sendMsgService;
    /**
     * 激活码激活用户
     */
    @PostMapping("/activation")
//    @RequiresPermissions("account:yxtuserinfo:save")
    public R activation(@RequestBody String code) {
        // 判断用户是否已经激活
        AccountEntity entity = accountService.getById(getUserId(true));
        if (entity.getActivating()) {
            return R.error("您已经激活，无需再次激活！");
        }
        // 判断激活码是否已经被使用
        Boolean aBoolean = userActivationService.checkActivationCode(code);
        if (aBoolean) {
            String s = AESUtil.codeUseCFBDecrypt(code);
            // 存入激活码激活记录表
            Boolean bBoolean = userActivationService.saveRecord(s, entity.getId(), code);
            if (bBoolean) {
                sendMsgService.sendCommon(MqConstant.UserUpgradeConstant.USER_UPGRADE_EXCHANGE, MqConstant.UserUpgradeConstant.USER_UPGRADE_ROUTER
                        , entity.getId().toString());
                return R.ok("激活成功！");
            }
            return R.error("激活失败！");
        } else {
            return R.error("验证码已被使用！");
        }
    }

    /**
     * 个人会员信息
     */
    @GetMapping("/info")
    public R info() {
        AccountEntity entity = accountService.getById(getUserId(true));
        return R.ok().put("data", entity);
    }

    /**
     * 个人会员账户信息
     */
    @GetMapping("/getAccountInfo")
    public R getAccountInfo() {
        Long userId = getUserId(true);
        Long shopId = getSubShopById(userId);//隶属商家id
        AccountVO vo = accountService.getAccountSubInfo(userId, shopId);
        return R.ok().put("data", vo);
    }

    /**
     * 个人会员账户信息及店铺等级
     */
    @GetMapping("/getAccountInfo/{shopId}")
    public R getShopAccountInfo(@PathVariable("shopId") Long shopId) {
        AccountVO vo = accountService.getShopAccountInfo(getUserId(true), shopId);
        return R.ok().put("data", vo);
    }

    /**
     * APP -个人会员账户信息
     */
    @GetMapping("/app-account-info")
    public R getAppAccountInfo() {
        AccountAppVO vo = accountService.appAccountInfo(getUserId(true));
        vo.getAuthSuccess();
        return R.ok().put("data", vo);
    }

    /**
     * APP -- 修改密码
     */
    @PostMapping("/updatePass")
    public R updatePass(@RequestBody PasswordForm form) {
        //更新密码
        accountService.updatePass(getMember(), form.getPassword(), form.getNewPassword());
        return R.ok();
    }

    /**
     * APP -- 忘记密码
     */
    @PostMapping("/forgetPass")
    public R forgetPass(@RequestBody PasswordForm form) {
        ValidatorUtils.validateEntity(form);

        //校验验证码
        commonService.checkVerCode(form.getMobile(), form.getCaptcha());
        //更新密码
        accountService.forgetPass(form);

        return R.ok();
    }

    /**
     * APP -- 更换手机号
     */
    @PostMapping("/changeMobile")
    public R changeMobile(@RequestBody MobileForm form) {
        ValidatorUtils.validateEntity(form);

        if (form.getMobile().equals(form.getNewMobile())) {
            throw new RRException(MemberException.MOBILE_THE_SAME);
        }
        //校验验证码
        commonService.checkVerCode(form.getNewMobile(), form.getCaptcha());
        //更换手机号
        accountService.changeMobile(form, getUserId(true));

        return R.ok();
    }

    /**
     * 我的团队
     */
    @GetMapping("/myPartner")
    public R myPartner() {
        Long userId = getUserId(true);
        List<AccountDownVO> vos = new ArrayList<>();
        if (userId != 0) {
            vos = accountService.myPartner(userId);
        }
        int num = 0;//我的伙伴个数
        if (vos != null && vos.size() > 0) {
            num = vos.size();
        }

        return R.ok().put("data", vos).put("num", num);
    }

    /**
     * 我的伙伴个数
     */
    @GetMapping("/myPartnerNum")
    public R myPartnerNum() {
        Long userId = getUserId(true);
        int num = 0;
        if (userId != 0) {
            num = accountService.myPartnerNum(userId);
        }

        return R.ok().put("data", num);
    }

    /**
     * APP 设备管理 个人信息
     */
    @GetMapping("/app-info")
    public R appInfo(@RequestParam Map<String, Object> params) {
        AccountAppVO vo = accountService.appInfo(setUserId(params));

        return R.ok().put("data", vo);
    }

    /**
     * 判断该手机号是否注册
     **/
    @GetMapping("/verify-mobile/{mobile}")
    public R logout(@PathVariable("mobile") String mobile) {

        AccountEntity accountEntity = accountService.getByMobile(mobile);
        boolean b = false;
        if (accountEntity != null) {
            b = true;
        }
        return R.ok().put("data", b);
    }

    /**
     * 退出登录
     **/
    @PostMapping("/logout")
    public R logout(HttpServletRequest request) {
        String token = request.getHeader("token");
        //获取用户
        String userId = redisUtils.get(RedisKeys.getWxTokenConfigKey(token));

        //清除缓存中的token
        if (StringUtils.isNotBlank(token)) {
            redisUtils.delete(RedisKeys.getWxTokenConfigKey(token));
        }
        //清除缓存中unipush的客户端ID
        if (StringUtils.isNotBlank(userId)) {
            redisUtils.delete(RedisKeys.getPushCid(userId));
        }

        return R.ok();
    }

    /**
     * 运营中心-个人信息
     */
    @GetMapping("/operating/center/info")
    public R operatingCenterInfo() {
        OperatingCenterVO vo = accountService.operatingCenterInfo(getUserId(true));
        return R.ok().put("data", vo);
    }

    /**
     * 个人中心-设置-个人信息
     *
     * @param number 当前app的版本号
     * @return
     */
    @GetMapping("/center/setting/info")
    public R centerSettingInfo(Integer number) {
        CenterSettingVO vo = accountService.centerSettingInfo(getUserId(true), number);
        return R.ok().put("data", vo);
    }

    /**
     * 获取配置
     */
    @GetMapping("/config")
    public R getConfig() {
        AliPayConfig config = accountService.getConfig();
        return R.ok().put("data", config);
    }

    /**
     * 累计邀请统计
     */
    @GetMapping("/updatestatistics")
    public R updateStatistics() {
        Long userId = getUserId(true);
        Integer allActivatingCount = accountService.getAllActivatingCount(userId);
        Integer allChildActivatingCount = accountService.getChildActivatingCount(userId);

        // 获取惠选区总消费
        BigDecimal obtainActivationTotalPrice = userInfoDao.getObtainActivationTotalPrice(userId);
        if (obtainActivationTotalPrice == null) {
            obtainActivationTotalPrice = new BigDecimal(0);
        }


        PointGradeConfigDTO config = pointGradeConfigService.info();
//        System.out.println("消费金额" + config.getConsumerStandards());
//        System.out.println("用户消费" + obtainActivationTotalPrice);
        HashMap<String, Object> map = new HashMap<>();
        map.put("count", config.getGeNumPeople());
        map.put("num_direct_referrals", config.getNumDirectReferrals());
        map.put("consumerStandards", config.getConsumerStandards());
        map.put("existing_count", allActivatingCount);
        map.put("all_child_activating_count", allChildActivatingCount);
        map.put("existing_consumerStandards", obtainActivationTotalPrice);
        map.put("without_count", config.getGeNumPeople() - allActivatingCount);
        map.put("child_without_count", (config.getNumDirectReferrals() - allChildActivatingCount) < 0?0:(config.getNumDirectReferrals() - allChildActivatingCount));
        map.put("without_consumerStandards", config.getConsumerStandards().subtract(obtainActivationTotalPrice));

        return R.ok().put("data", map);
    }

    /**
     * 根据分享码查询用户
     */
    @GetMapping("/getByCode")
    public R getByCode(@RequestParam("code") String code) {
        AccountAppVO vo = accountService.getByShareCode(code);
        return R.ok().put("data", vo);
    }

    /**
     * 根据升级条件重新判断用户是否升级
     */
    @GetMapping("/updateTeamLevel")
    public R updateTeamLevel() {
        List<HashMap<String,Object>> list = accountService.updateTeamLevel();
        accountService.updateGradeById(list);
        System.out.println(list);
        System.out.println("1111");
        return R.ok();
    }
}
